package com.example.jvm;

import java.util.ArrayList;
import java.util.List;

public class MainTest {

    public static void main(String[] args) throws Exception {
        test5();
        Thread.sleep(100000000);
    }

    /**
     * 测试类加载信息 jstat -class vmid
     */
    private static class VmClass2{
        static {

        }
    }

    /**
     * 配置jvm选项
     *
     * -Xmx20m -Xms5m -XX:+PrintGCDetails
     */
    private static void test(){
        // byte[] bytes = new byte[1*1024*1024];
        //System.gc();
    }

    private static void test2(){
        byte[] bytes1 = new byte[500*1024];
        byte[] bytes2 = new byte[500*1024];
        //byte[] bytes3 = new byte[500*1024];
        // byte[] bytes2 = new byte[10*1024*1024];
    }

    private static void test3() throws InterruptedException {
        VmClass vmClass = new VmClass();
        VmClass2 vmClass2 = new VmClass2();
        while (true) {
            byte[] bytes = new byte[4* 1024 * 1024];
            System.out.println("Xmx=" + Runtime.getRuntime().maxMemory() / 1024.0 / 1024 + "M");    //系统的最大空间
            System.out.println("free mem=" + Runtime.getRuntime().freeMemory() / 1024.0 / 1024 + "M");  //系统的空闲空间
            System.out.println("total mem=" + Runtime.getRuntime().totalMemory() / 1024.0 / 1024 + "M");  //当前可用的总空间
            System.out.println("========================================");
            Thread.sleep(500);
        }
    }

    /**
     * 测试oom
     * @throws Exception
     */
    private static void test4() throws Exception{
        List<byte[]> list=new ArrayList<>();
        List<VmClass2> list1=new ArrayList<>();
        System.out.println(list.hashCode()+"=="+list1);
        while (true){
            byte[] bytes = new byte[1* 1024 * 1024];
            VmClass2 vmClass2 = new VmClass2();
            Thread.sleep(500);
            list.add(bytes);
            list1.add(vmClass2);
        }
    }

    /**
     * 测试线程状态 jstack
     * @throws Exception
     */
    private static void test5() throws Exception{

        //睡眠状态
        new Thread(()->{
            try {
                Thread.sleep(10000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"睡眠线程1").start();

        //死锁
        Object o=new Object();
        Object o1=new Object();
        new Thread(()->{

            synchronized (o){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("死锁线程1 获得 o锁");

                synchronized (o1){
                    System.out.println("死锁线程1 获得 o1锁");
                }
            }
        },"死锁线程1").start();

        new Thread(()->{

            synchronized (o1){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("死锁线程2 获得 o1锁");

                synchronized (o){
                    System.out.println("死锁线程2 获得 o锁");
                }
            }
        },"死锁线程2").start();

        System.out.println("线程执行完毕");
    }
}
